package com.sxt;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 谭梦寻
 * @version 1.1
 * 创建窗口
 * 问题1 ：红线有时候没有生成
 * 问题2 ：失败后药水没有刷新
 */
public class GameWin extends JFrame {
    //    设置游戏状态 0表示未开始 1表示运行中 2表示商店 3 失败 4 胜利
    static int state;


    //    创建一个集合 存放多个金块 石块
    List<Object> objectList = new ArrayList<>();

    //  创建一个背景类
    Bg bg = new Bg();
    //    创建一个红线类
    Line line = new Line(this);

    //    创建一个金块
//    Gold gold = new Gold();
//创建多个金块
//    在类当中不能直接写for循环 只能给他一个无参构造 或者设置一个代码块
    {
//    设置布尔类型 表示是否可放置
        boolean isPlace = true;
//    设置金块出现的概率
        for (int i = 0; i < 8; i++) {
            double random = Math.random();
            //        检测物体堆叠
            Gold gold;
            if (random < 0.3) {
                gold = new MinGold();//生成小金块
            } else if (random < 0.7) {
                gold = new Gold();//生成正常金块
            } else {//生成大金块
                gold = new MaxGold();
            }
//        判断是否重叠
            for (Object obj : objectList) {
                if (gold.getRec().intersects(obj.getRec())) {
//                不可放置 需要重新生成
                    isPlace = false;
                }
            }
            if (isPlace) {
                objectList.add(gold);
            } else {
                isPlace = true;
//          重新执行循环生成金块
                i--;
            }
        }

//        生成石块

        for (int i = 0; i < 5; i++) {
            Rock rock = new Rock();
            for (Object obj : objectList) {
                if (rock.getRec().intersects(obj.getRec())) {
//                    如果重合
                    isPlace = false;
                }
            }
            if (isPlace) {
//                没有重叠
                objectList.add(rock);
            } else {
                isPlace = true;
                i--;
            }

        }
    }


    /*    初始化一块画布 --双缓存解决闪烁问题
          将所有绘制的图案放在一块画布中
          然后将画布放入窗口
    */
    Image offScreenImage;

    //    初始化窗口信息
    void launch() {
//        窗口是否可见
        this.setVisible(true);
//        设置窗口大小
        this.setSize(768, 1000);
//        设置窗口位置
        this.setLocationRelativeTo(null);//使得窗口居中
//        设置窗口标题
        this.setTitle("黄金矿工");
//        设置关闭窗口的方法
        setDefaultCloseOperation(EXIT_ON_CLOSE);//点击右上角也能关闭窗口

//        创建一个点击事件
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                switch (state) { //默认值是0
                    case 0: //未开始  点击鼠标右键开始游戏
                        if (e.getButton() == 3) {//鼠标左键是1 右键是3 滚轮是2
                            state = 1;
                            bg.startTime = System.currentTimeMillis();
                        }
                        break;
                    case 1: //运行中
//                左右摇摆 鼠标左键是1 右键是3 滚轮是2
//                点击左键
                        if (e.getButton() == 1 && line.state == 0) {
                            line.state = 1;
                        }
//                鼠标右键事件 抓取返回
                        if (e.getButton() == 3 && line.state == 3 && Bg.waterNum > 0) {
//                    药水减少
                            Bg.waterFlag = true;
                            Bg.waterNum--;
                        }
                        break;
                    case 2: //商店
//                  点击鼠标左键购买
                        if (e.getButton() == 1) {
                            bg.shop = true;
                        }
                        if (e.getButton() == 3) {
//                            直接进入下一一关 并重新计时
                            state = 1;
                            bg.startTime = System.currentTimeMillis();
                        }
                        break;
                    case 3: //失败
//                        break;
                    case 4: //胜利
                        if (e.getButton() == 1) {
//                            返回状态 0 重置元素
                            state = 0;
                            bg.reGame();
                            line.reGame();
                        }
                        break;
                    default:

                }

            }
        });
//          添加循环 让图片不停的绘制
        while (true) {
            repaint();
//      调用是否进入下一关的函数
            nextLevel();
//            设置绘制间隔时间
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //    进入下一关
    public void nextLevel() {
        if (bg.gameTime() && state == 1) {
//    如果我的积分大于目标积分 通过类名直接调用静态属性 通过对象名调用非静态属性
            if (Bg.count >= bg.goal) {
                if (Bg.level > 5) {//过5关成功
                    state = 4;
                } else {
                    state = 2;
                    Bg.level++;
//                    进入下一关重置时间
//                    bg.startTime = System.currentTimeMillis();
                }
//            System.out.println("进入下一关");
            } else {//游戏失败
                state = 3;
            }

//            每次进入下一关 释放之前的窗体 且重置物体
            dispose();
            GameWin gameWin = new GameWin();
            gameWin.launch();//重新绘制
        }

    }

    //    写一个绘制方法
    @Override
    public void paint(Graphics g) {
        offScreenImage = this.createImage(768, 1000);//大小和窗体大小相同
//        给画笔添加画笔
        Graphics gImages = offScreenImage.getGraphics();
//        传入画笔
        bg.paintSelf(gImages);
//        背景在任何时候都会绘制 但线和物体只有在游戏运行时才会绘制
        if (state == 1) {
            //        先画金块后画线
//        利用增强for循环遍历集合
            for (Object obj : objectList) {
                obj.paintSelf(gImages);
            }
            line.paintSelf(gImages);//画线
            //        单个金块的绘制
//        gold.paintSelf(gImages);
        }

//        将画布绘制到窗口中
        g.drawImage(offScreenImage, 0, 0, null);
    }

    //    程序的入口
    public static void main(String[] args) {
        GameWin gameWin = new GameWin();
        gameWin.launch();
    }
}
